use std::time::Duration;

use anyhow::anyhow;
use bytes::Bytes;
use reqwest::header;
use salvo::http::HeaderMap;
use serde::de::DeserializeOwned;
use serde::Serialize;

/// 请求客户端
pub struct HttpClient {
    client: reqwest::Client,
}

impl HttpClient {
    pub fn builder( ) -> anyhow::Result<HttpClient> {
        let mut headers = HeaderMap::new();
        headers.insert(
            header::USER_AGENT,
            header::HeaderValue::from_static("Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/130.0.0.0 Safari/537.36 Edg/130.0.0.0"),
        );
        let client = reqwest::Client::builder()
            .timeout(Duration::from_secs(300))
            .connect_timeout(Duration::from_secs(300))
            .default_headers(headers)
            .build()?;
        Ok(HttpClient { client })
    }

    pub async fn post<T: Serialize + ?Sized>(
        &self,
        url: &str,
        params: &T,
    ) -> anyhow::Result<String> {
        let response = self.client.post(url).json(params).send().await?;
        if response.status().is_success() {
            let resp = response.text().await?;
            Ok(resp)
        } else {
            Err(anyhow!("response is not success "))
        }
    }

    pub async fn post_entry<T: Serialize + ?Sized, R: DeserializeOwned>(
        &self,
        url: &str,
        params: &T,
    ) -> anyhow::Result<R> {
        let response = self.client.post(url).json(params).send().await?;
        if response.status().is_success() {
            let resp = response.json::<R>().await?;
            Ok(resp)
        } else {
            Err(anyhow!("response is not success "))
        }
    }

    /// 发送二进制文件
    pub async fn post_betyes(&self, url: &str, body: Bytes) -> anyhow::Result<String> {
        let response = self.client.post(url).body(body).send().await?;
        if response.status().is_success() {
            let resp = response.text().await?;
            return Ok(resp);
        }
        Err(anyhow!("response is not success"))
    }

    pub async fn get_entry<T: DeserializeOwned>(&self, url: &str) -> anyhow::Result<T> {
        let response = self.client.get(url).send().await?;
        if response.status().is_success() {
            let t = response.json::<T>().await?;
            return Ok(t);
        }
        Err(anyhow!("get entry error"))
    }
    /// get方法
    pub async fn get(&self, url: &str) -> anyhow::Result<String> {
        let response = self.client.get(url).send().await?;
        if response.status().is_success() {
            let resp = response.text().await?;
            return Ok(resp);
        }
         Err(anyhow!("response is not success"))
    }
}
